using LiJ.Common.Core;
using LiJ.Common.Extention;
using LiJ.Http.Mos;
using LiJ.Framework.OAuth.Mos;
using System;
using System.Text;
using System.Threading.Tasks;

namespace LiJ.Framework.OAuth
{
	/// <summary>
	/// oauth 授权接口
	/// </summary>
	public class WxOauthApi : WxOauthBaseApi
	{
		/// <summary>
		/// default constructor
		/// </summary>
		/// <param name="config">配置信息，如果这里不传，需要在程序入口静态 WxBaseApi.DefaultConfig 属性赋值</param>
		public WxOauthApi(AppConfig config = null)
			: base(config)
		{
		}

		/// <summary>
		/// 获取授权地址
		/// </summary>
		/// <param name="redirectUri">授权后重定向的回调链接地址</param>
		/// <param name="state"> 需要回传的值 </param>
		/// <param name="type">授权客户端类型，如果是pc，则生成的是微信页面二维码授权页</param>
		/// <returns>授权的地址【如果 ApiConfig.OperateMode==AppOperateMode.ByAgent 回调除了 code 和 state 参数，还会有appid 】</returns>
		public string GetAuthorizeUrl(string redirectUri, string state, AuthClientType type)
		{
			if (redirectUri.Contains("://"))
			{
				redirectUri = redirectUri.UrlEncode();
			}
			StringBuilder stringBuilder = new StringBuilder("https://open.weixin.qq.com/connect/");
			object obj;
			string value;
			switch (type)
			{
			case AuthClientType.Web:
				stringBuilder.Append("qrconnect?appid=").Append(base.ApiConfig.AppId).Append("&redirect_uri=")
					.Append(redirectUri)
					.Append("&response_type=code&scope=snsapi_login");
				break;
			default:
				obj = "snsapi_userinfo";
				goto IL_006c;
			case AuthClientType.InnerSilence:
				{
					obj = "snsapi_base";
					goto IL_006c;
				}
				IL_006c:
				value = (string)obj;
				stringBuilder.Append("oauth2/authorize?appid=").Append(base.ApiConfig.AppId).Append("&redirect_uri=")
					.Append(redirectUri)
					.Append("&response_type=code&scope=")
					.Append(value);
				break;
			}
			stringBuilder.Append("&state=").Append(state);
			if (base.ApiConfig.OperateMode == AppOperateMode.ByAgent)
			{
				stringBuilder.Append("&component_appid=").Append(base.ApiConfig.ByAppId);
			}
			stringBuilder.Append("#wechat_redirect");
			return stringBuilder.ToString();
		}

		/// <summary>
		/// 获取授权access_token   (每个用户都是单独唯一)
		/// </summary>
		/// <param name="code">填写第一步获取的code参数</param>
		/// <returns></returns>
		public async Task<WxGetOauthAccessTokenResp> GetOauthAccessTokenAsync(string code)
		{
			StringBuilder stringBuilder = new StringBuilder("https://api.weixin.qq.com");
			if (base.ApiConfig.OperateMode == AppOperateMode.ByAgent)
			{
				Func<AppConfig, string> agentAccessTokenFunc = WxOauthConfigProvider.AgentAccessTokenFunc;
				string value = (agentAccessTokenFunc != null) ? agentAccessTokenFunc(base.ApiConfig) : null;
				if (string.IsNullOrEmpty(value))
				{
					throw new ArgumentNullException("AgentAccessToken", "AgentAccessToken未发现，请检查 WxOauthConfigProvider 下 AgentAccessTokenFunc 委托是否为空或者返回值不正确！");
				}
				stringBuilder.Append("/sns/oauth2/component/access_token?appid=").Append(base.ApiConfig.AppId).Append("&code=")
					.Append(code)
					.Append("&grant_type=authorization_code")
					.Append("&component_appid=")
					.Append(base.ApiConfig.ByAppId)
					.Append("&component_access_token=")
					.Append(value);
			}
			else
			{
				stringBuilder.Append("/sns/oauth2/access_token?appid=").Append(base.ApiConfig.AppId).Append("&secret=")
					.Append(base.ApiConfig.AppSecret)
					.Append("&code=")
					.Append(code)
					.Append("&grant_type=authorization_code");
			}
			LHttpRequest request = new LHttpRequest
			{
				AddressUrl = stringBuilder.ToString(),
				HttpMothed = HttpMothed.Get
			};
			return await base.RestCommonJson<WxGetOauthAccessTokenResp>(request, null);
		}

		/// <summary>
		///   刷新当前用户授权Token
		/// </summary>
		/// <param name="refreshToken">授权接口刷新调用凭证</param>
		/// <returns></returns>
		public async Task<WxGetOauthAccessTokenResp> RefreshOauthAccessTokenAsync(string refreshToken)
		{
			StringBuilder stringBuilder = new StringBuilder("https://api.weixin.qq.com");
			if (base.ApiConfig.OperateMode == AppOperateMode.ByAgent)
			{
				Func<AppConfig, string> agentAccessTokenFunc = WxOauthConfigProvider.AgentAccessTokenFunc;
				string value = (agentAccessTokenFunc != null) ? agentAccessTokenFunc(base.ApiConfig) : null;
				if (string.IsNullOrEmpty(value))
				{
					throw new ArgumentNullException("AgentAccessToken", "AgentAccessToken未发现，请检查 WxOauthConfigProvider 下 AgentAccessTokenFunc 委托是否为空或者返回值不正确！");
				}
				stringBuilder.Append("/sns/oauth2/component/refresh_token?appid=").Append(base.ApiConfig.AppId).Append("&grant_type=refresh_token")
					.Append("&component_appid=")
					.Append(base.ApiConfig.ByAppId)
					.Append("&component_access_token=")
					.Append(value);
			}
			else
			{
				stringBuilder.Append("/sns/oauth2/refresh_token?appid=").Append(base.ApiConfig.AppId).Append("&grant_type=refresh_token");
			}
			stringBuilder.Append("&refresh_token=").Append(refreshToken);
			LHttpRequest request = new LHttpRequest
			{
				AddressUrl = stringBuilder.ToString(),
				HttpMothed = HttpMothed.Get
			};
			return await base.RestCommonJson<WxGetOauthAccessTokenResp>(request, null);
		}

		/// <summary>
		/// 获取用户信息
		/// </summary>
		/// <param name="accessToken">授权接口调用凭证</param>
		/// <param name="openId">用户的唯一标识</param>
		/// <returns></returns>
		public async Task<WxGetOauthUserResp> GetWxOauthUserInfoAsync(string accessToken, string openId)
		{
			LHttpRequest request = new LHttpRequest
			{
				AddressUrl = string.Format("{0}/sns/userinfo?access_token={1}&openid={2}", "https://api.weixin.qq.com", accessToken, openId),
				HttpMothed = HttpMothed.Get
			};
			return await base.RestCommonJson<WxGetOauthUserResp>(request, null);
		}

		/// <summary>
		/// 检验授权凭证（access_token）是否有效
		/// </summary>
		/// <param name="accessToken">授权接口调用凭证</param>
		/// <param name="openId">用户的唯一标识</param>
		/// <returns></returns>
		public async Task<WxBaseResp> CheckOauthAccessTokenAsync(string accessToken, string openId)
		{
			string addressUrl = string.Format("{0}/sns/auth?access_token={1}&openid={2}", "https://api.weixin.qq.com", accessToken, openId);
			LHttpRequest request = new LHttpRequest
			{
				AddressUrl = addressUrl,
				HttpMothed = HttpMothed.Get
			};
			return await base.RestCommonJson<WxBaseResp>(request, null);
		}
	}
}
